package com.xbts.screen.monitor.domain.token;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * token存储方式为Mysql
 */
public class MysqlTokenStore implements TokenStore {
    public static final Logger logger = LoggerFactory.getLogger(MysqlTokenStore.class);
    public static final Object lock = new Object();

    public static String INSERT_TOKEN_INFO = "insert into token(token_key,token_value) values(?, ?)";
    public static String QUERY_TOKEN_INFO = "select id,token_key,token_value from token";
    public static String UPDATE_TOKEN_INFO = "update token set token_value = ? where token_key = ?";
    public static String DELETE_TOKEN_ALL = "delete from token";

    private JdbcTemplate jdbcTemplate;

    public MysqlTokenStore(){}

    public JdbcTemplate getJdbcTemplate(){
        if(jdbcTemplate == null){
            synchronized (lock){
                if(jdbcTemplate == null){
                    jdbcTemplate = new JdbcTemplate(getDataSource());
                }
            }
        }
        return jdbcTemplate;
    }

    /**
     * 存储token
     * @param:key 键
     * @param:token 值
     * **/
    public void tokenStore(String tokenKey, Token token){
        INSERT_TOKEN_INFO = INSERT_TOKEN_INFO.replaceFirst("[?]", tokenKey);
        INSERT_TOKEN_INFO = INSERT_TOKEN_INFO.replaceFirst("[?]", "\'" + JSON.toJSONString(token) + "\'");
        jdbcTemplate.execute(INSERT_TOKEN_INFO);
    }

    /**
     * 获取token信息
     * @return List<Token>
     * **/
    public Map<String, Token> getToken(){
        RowMapper<MysqlStoredToken> rowMapper = new BeanPropertyRowMapper<MysqlStoredToken>(MysqlStoredToken.class);
        List<MysqlStoredToken> mysqlStoredTokens = jdbcTemplate.query(QUERY_TOKEN_INFO, rowMapper);
        Map<String, Token> tokens = new HashMap<String, Token>();
        for(int i = 0; i < mysqlStoredTokens.size(); i++){
            MysqlStoredToken mysqlStoredToken = mysqlStoredTokens.get(i);
            Token token = JSON.parseObject(mysqlStoredToken.getToken_value(), Token.class);
            tokens.put(mysqlStoredToken.getToken_key(),token);
        }
        return tokens;
    }

    /**
     * 更新token信息
     * @param token
     * **/
    public void updateToken(String key, Token token){
        UPDATE_TOKEN_INFO = UPDATE_TOKEN_INFO.replaceFirst("[?]", "\'" + JSON.toJSONString(token) + "\'");
        UPDATE_TOKEN_INFO = UPDATE_TOKEN_INFO.replaceFirst("[?]", "\'" + key + "\'");
        jdbcTemplate.execute(UPDATE_TOKEN_INFO);
    }

    /**
     * 删除token信息
     * **/
    public void deleteToken(){
        jdbcTemplate.execute(DELETE_TOKEN_ALL);
    }

    /**
     * 获取数据源
     * @return Datasource
     * **/
    public DataSource getDataSource(){
        DriverManagerDataSource dataSource = null;
        Properties properties = new Properties();

        try{
            //加载配置信息
            properties.load(this.getClass().getClassLoader().getResourceAsStream("application.properties"));
            String driverClassName = properties.getProperty("spring.datasource.driver-class-name");
            String url = properties.getProperty("spring.datasource.url");
            String username = properties.getProperty("spring.datasource.username");
            String password = properties.getProperty("spring.datasource.password");

            //设置数据源
            dataSource = new DriverManagerDataSource();
            dataSource.setDriverClassName(driverClassName);
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
        }catch (Exception e){
            logger.error("an error occurred while getting the data source,errMsg:{}", e.getMessage());
            e.printStackTrace();
        }
        return dataSource;
    }

//    public static void main(String[] args) {
//        Map<String, Token> tokens = new MysqlTokenStore().getToken();
//        Token token = tokens.get("system");
//        token.setTtl(22222L);
//
//        new MysqlTokenStore().updateToken("system", token);
//    }
}
